home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d13
/
nuf210.arc
/
GETARGS.C
< prev
next >
Wrap
Text File
|
1990-06-14
|
20KB
|
722 lines
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include "nufind.h"
#include "queue.h"
struct DateSel {
unsigned Date;
int Swt;
};
char *RootPath(char *CurDir, char *RelPath, char *FullPath);
void GetStdIn(QUE_DEF * Que, char *Prompt);
int GetList(QUE_DEF * Que, char *argv[], int i, char *Prompt, char *PathName);
void ErrorExit(char *Format,...);
void ErrorMsg(char *Format,...);
void ExceptionMsg(char *Format,...);
int GetAttr(char **Str, int i);
int MakeDir(char *Name);
int GetDate(char **argv, int i, struct DateSel * Date);
long GtoJ(unsigned m, unsigned d, unsigned y);
void JtoG(long Julian, int *Month, int *Day, int *Year);
int isdevice(int handle);
int GetDirRef(char **Ref, char **argv, int i);
int GetFileRef(INFO_BLOCK ** Ref, char **argv, int i);
void GetPath(QUE_DEF * Q, char *Arg);
int GetYorN(char *Message,...);
int CheckPath (QUE_DEF *Q, char *Name);
void SetCopyMove (char *argv[], int *i, int *Swt);
static char *OptTable[] = {
#define O_NAME 0
"name",
#define O_NAME_SHORT 1
"n",
#define O_NOT_NAME 2
"^name",
#define O_NOT_NAME_SHORT 3
"^n",
#define O_FNAME 4
"fname",
#define O_FNAME_SHORT 5
"fn",
#define O_NOT_FNAME 6
"^fname",
#define O_NOT_FNAME_SHORT 7
"^fn",
#define O_SILENT 8
"s",
#define O_PRINT 9
"p",
#define O_LS 10
"ls",
#define O_LD 11
"ld",
#define O_REMOVE 12
"rm",
#define O_REMOVE_ALL 13
"rma",
#define O_ATTR 14
"attr",
#define O_NOT_ATTR 15
"^attr",
#define O_ATTR_ON 16
"attr+",
#define O_ATTR_OFF 17
"attr-",
#define O_NO_RECUR 18
"nr",
#define O_COPY 19
"cp",
#define O_MOVE 20
"mv",
#define O_SINCE 21
"si",
#define O_BEFORE 22
"be",
#define O_SIZE 23
"size",
#define O_REMOVE_DIR 24
"rmdir",
#define O_EXEC 25
"exec",
#define O_EXEC_SHORT 26
"ex",
#define O_TREE 27
"t",
#define O_SUM 28
"sum",
#define O_EXIST 29
"exist",
#define O_NOT_EXIST 30
"^exist",
#define O_COMP 31
"comp",
#define O_NOT_COMP 32
"^comp",
#define O_LT 33
"lt",
#define O_LE 34
"le",
#define O_GT 35
"gt",
#define O_GE 36
"ge",
#define O_LT_DATE 37
"ltdate",
#define O_LE_DATE 38
"ledate",
#define O_GT_DATE 39
"gtdate",
#define O_GE_DATE 40
"gedate",
#define O_RELATIVE 41
"re",
#define O_NOT_PATH 42
"^dir",
#define O_NOT_PATH_SHORT 43
"^d",
#define O_MOVE_TREE 44
"mt",
#define O_COPY_TREE 45
"ct",
#define O_COPY_TREE_DATE 46
"cto",
#define O_COPY_DATE 47
"cpo",
#define O_KILL 48
"kill",
#define O_INVALID 49
""
};
void
GetArgs (char *argv[], int i) {
extern QUE_DEF Paths, ExcPaths;
extern QUE_DEF IncNameQueue, ExcNameQueue;
extern QUE_DEF IncPathQueue, ExcPathQueue;
extern char DestDir[], CurDir[];
extern int PrtSwt, LsSwt, LdSwt, RmSwt, RmSwtA, AttrSwt, NotAttrSwt;
extern int AttrOnSwt, AttrOffSwt, RecurSwt, CopySwt, MoveSwt, RmDirSwt;
extern int SizeSwt, ExecSwt, TreeSwt, SumSwt, RelSwt, OldDate;
extern char AttrMask, NotAttrMask, AttrOnMask, AttrOffMask;
extern char *ExistRef, *NotExistRef, *CompRef, *NotCompRef;
extern INFO_BLOCK *LT_Ref, *LE_Ref, *GT_Ref, *GE_Ref;
extern INFO_BLOCK *LT_DateRef, *LE_DateRef, *GT_DateRef, *GE_DateRef;
extern char *CommandString;
extern unsigned TodayDate;
extern long Size;
extern struct DateSel Since, Before;
char *Arg, PathName[65];
int j;
for (; argv[i] != NULL; ++i) {
if (**(argv + i) != '-') continue;
Arg = (*(argv + i)) + 1;
for (j = 0; OptTable[j][0] != '\0'; ++j)
if (!strcmp(Arg, OptTable[j])) break;
switch (j) {
case O_NOT_PATH:
case O_NOT_PATH_SHORT:
for (++i; argv[i] != NULL && argv[i][0] != '-'; ++i)
GetPath(&ExcPaths, argv[i]);
if (argv[i][0] == '-') --i;
break;
case O_NAME:
case O_NAME_SHORT:
i = GetList(&IncNameQueue, argv, i, "-name:", NULL);
continue;
case O_NOT_NAME:
case O_NOT_NAME_SHORT:
i = GetList(&ExcNameQueue, argv, i, "-^name:", NULL);
continue;
case O_FNAME:
case O_FNAME_SHORT:
i = GetList(&IncPathQueue, argv, i, "-fname:", PathName);
continue;
case O_NOT_FNAME:
case O_NOT_FNAME_SHORT:
i = GetList(&ExcPathQueue, argv, i, "-^fname:", PathName);
continue;
case O_SILENT:
PrtSwt = 0;
break;
case O_PRINT:
PrtSwt |= 0x02;
break;
case O_LS:
LsSwt = 1;
PrtSwt &= 0xFE;
break;
case O_LD:
LdSwt = 1;
PrtSwt &= 0xFE;
break;
case O_REMOVE:
RmSwt = 1;
PrtSwt &= 0xFE;
break;
case O_REMOVE_ALL:
RmSwtA = 1;
PrtSwt &= 0xFE;
break;
case O_REMOVE_DIR:
RmDirSwt = 1;
PrtSwt &= 0xFE;
break;
case O_ATTR:
AttrMask = GetAttr(argv, ++i);
AttrSwt = 1;
break;
case O_NOT_ATTR:
NotAttrMask = GetAttr(argv, ++i);
NotAttrSwt = 1;
break;
case O_ATTR_ON:
AttrOnMask = GetAttr(argv, ++i);
PrtSwt &= 0xFE;
AttrOnSwt = 1;
break;
case O_ATTR_OFF:
AttrOffMask = GetAttr(argv, ++i);
PrtSwt &= 0xFE;
AttrOffSwt = 1;
break;
case O_NO_RECUR:
RecurSwt = 0;
break;
case O_COPY_TREE_DATE:
OldDate = 1;
case O_COPY_TREE:
TreeSwt = 1;
SetCopyMove(argv, &i, &CopySwt);
break;
case O_COPY_DATE:
OldDate = 1;
case O_COPY:
SetCopyMove(argv, &i, &CopySwt);
break;
case O_MOVE_TREE:
TreeSwt = 1;
RmDirSwt = 1;
SetCopyMove(argv, &i, &MoveSwt);
break;
case O_MOVE:
SetCopyMove(argv, &i, &MoveSwt);
break;
case O_SINCE:
i = GetDate(argv, i, &Since);
break;
case O_BEFORE:
i = GetDate(argv, i, &Before);
break;
case O_SIZE:
if ( argv[i + 1][0] == '\0'
|| (argv[i + 1][0] == '-' && !isdigit(argv[i + 1][1])) )
ErrorExit("\"%s\" Size argument required.\n", argv[i]);
else if (isdigit(argv[i + 1][0])) {
Size = atol(argv[++i]);
SizeSwt = 1;
}
else if (argv[i + 1][0] == '-' && isdigit(argv[i + 1][1])) {
Size = atol(argv[++i] + 1);
SizeSwt = 2;
}
else
ErrorExit("\"%s\" Invalid size - %s\n", argv[i],
argv[i + 1]);
break;
case O_EXEC:
case O_EXEC_SHORT:
if (argv[i + 1][0] == '\0' || argv[i + 1][0] == '-')
ErrorExit("\"%s\" Command required.\n", argv[i]);
ExecSwt = 1;
PrtSwt &= 0xFE;
CommandString = strdup(argv[++i]);
break;
case O_TREE:
TreeSwt = 1;
break;
case O_SUM:
SumSwt = 1;
break;
case O_EXIST:
i = GetDirRef(&ExistRef, argv, i);
break;
case O_NOT_EXIST:
i = GetDirRef(&NotExistRef, argv, i);
break;
case O_COMP:
i = GetDirRef(&CompRef, argv, i);
break;
case O_NOT_COMP:
i = GetDirRef(&NotCompRef, argv, i);
break;
case O_LT:
i = GetFileRef(<_Ref, argv, i);
break;
case O_LE:
i = GetFileRef(&LE_Ref, argv, i);
break;
case O_GT:
i = GetFileRef(>_Ref, argv, i);
break;
case O_GE:
i = GetFileRef(&GE_Ref, argv, i);
break;
case O_LT_DATE:
i = GetFileRef(<_DateRef, argv, i);
break;
case O_LE_DATE:
i = GetFileRef(<_DateRef, argv, i);
break;
case O_GT_DATE:
i = GetFileRef(>_DateRef, argv, i);
break;
case O_GE_DATE:
i = GetFileRef(&GE_DateRef, argv, i);
break;
case O_RELATIVE:
RelSwt = 1;
break;
case O_KILL:
RmSwt = 1;
RmDirSwt = 1;
PrtSwt &= 0xFE;
break;
default:
ErrorExit("Invalid option: %s", Arg);
}
}
}
int
GetList (QUE_DEF * Que, char *argv[], int i, char *Prompt, char *PathName) {
extern char CurDir[];
FILE *F1;
char Line[80];
if (!strcmp(argv[i + 1], "-")) {
GetStdIn(Que, Prompt);
++i;
}
else if (argv[i + 1][0] == '@') {
if ((F1 = fopen(&argv[i + 1][1], "r")) == NULL)
ErrorExit("I can't find index file: %s!\n", &argv[i + 1][1]);
while (fgets(Line, 79, F1) != NULL) {
if (Line[strlen(Line) - 1] == '\n') Line[strlen(Line) - 1] = '\0';
else ErrorExit("Index file: %s - Line too long\n %s\n",
&argv[i + 1][1], Line);
if (PathName != NULL) {
if ((Enque(Que, strlwr(RootPath(CurDir, Line, PathName))))
== NULL) {
ErrorMsg("Insufficient memory for input list.\n");
return (i);
}
}
else if ((Enque(Que, strlwr(Line))) == NULL) {
ErrorMsg("Insufficient memory for input list.\n");
return (i);
}
}
fclose(F1);
i += 1;
}
else {
for (++i; argv[i] != NULL && argv[i][0] != '-'; ++i)
if (PathName != NULL) {
if ((Enque(Que, strlwr(RootPath(CurDir, argv[i], PathName))))
== NULL) {
ErrorMsg("Insufficient memory for input list.\n");
return (i);
}
}
else if ((Enque(Que, strlwr(argv[i]))) == NULL) {
ErrorMsg("Insufficient memory ofr input list.\n");
return (i);
}
--i;
}
return (i);
}
void
GetStdIn (QUE_DEF *Que, char *Prompt) {
char Line[80];
while (1) {
if (isdevice(fileno(stdin))) fprintf(stderr, "%s ", Prompt);
if (gets(Line) == NULL) break;
if (Line[0] == '\0') break;
if ((Enque(Que, Line)) == NULL) {
ErrorMsg("Insufficient memory for input lst.\n");
return;
}
}
}
int
GetAttr (char **Str, int i) {
char Ch;
int j, Mask;
if (Str[i][0] == '\0' || Str[i][0] == '-')
ErrorExit("\"%s\" must be followed by a list of attributes.", Str[i - 1]);
Mask = j = 0;
while ((Ch = tolower(Str[i][j++])) != '\0') switch (Ch) {
case 'r':
Mask |= 0x01;
break;
case 'h':
Mask |= 0x02;
break;
case 's':
Mask |= 0x04;
break;
case 'v':
Mask |= 0x08;
break;
case 'd':
Mask |= 0x10;
break;
case 'a':
Mask |= 0x20;
break;
default:
ErrorExit("\"%s\" Invalid attribute: %s", Str[i - 1], Str[i]);
}
return (Mask);
}
int
MakeDir (char *Name) {
extern QUE_DEF NoCreateQ;
struct ffblk DirBlk;
char *p, Temp[66];
int Result;
if (NoCreateQ.Count != 0)
if ( CheckPath(&NoCreateQ, Name) != 0 ) return(0);
p = strrchr(Name, '\\');
if (*(p - 1) == ':') return (0);
*p = '\0';
Result = findfirst(Name, &DirBlk, 0xFF);
if (Result || (DirBlk.ff_attrib & FA_DIREC) == 0) {
if ((Result = MakeDir(Name)) != 0) return (Result);
if ( !GetYorN("Directory %s does not exist. Create it ", Name) ) {
strcpy(Temp, Name);
strcat(Temp, "\\*");
Enque(&NoCreateQ, Temp);
return(2);
}
if ((Result = mkdir(Name)) == 0) {
strcpy(Temp, Name);
strcat(Temp, "\\*");
Enque(&ExcPathQueue, Temp);
}
else {
strcpy(Temp, Name);
strcat(Temp, "\\*");
Enque(&NoCreateQ, Temp);
}
}
*p = '\\';
return (Result);
}
int
GetDate (char **argv, int i, struct DateSel * Date) {
unsigned long Today;
int Arg1, Arg2, Arg3;
int Year, Month, Day;
char *p, Temp[3], *Str;
if ( (argv[i + 1] == NULL) || (argv[i + 1][0] == '\0')
|| (argv[i + 1][0] == '-' && !isdigit(argv[i + 1][1]))) {
Date->Date = TodayDate;
Date->Swt = 1;
return (i);
}
if (argv[i + 1] != NULL && isdigit(argv[i + 1][0])) {
Str = argv[++i];
p = &Str[strcspn(Str, "-/")];
if (*p != 0) {
*p = '\0';
Arg1 = atoi(Str);
Str = ++p;
p = &Str[strcspn(Str, "-/")];
if (*p == '\0')
ErrorExit("\"%s\" Invalid date - %s\n", argv[i - 1], argv[i]);
*p = '\0';
Arg2 = atoi(Str);
Arg3 = atoi(p + 1);
}
else if (strlen(Str) > 2) {
strncpy(Temp, Str, 2);
Temp[2] = '\0';
Arg1 = atoi(Temp);
strncpy(Temp, Str + 2, 2);
Temp[2] = '\0';
Arg2 = atoi(Temp);
strncpy(Temp, Str + 4, 2);
Temp[2] = '\0';
Arg3 = atoi(Temp);
}
else {
Today = GtoJ((TodayDate >> 5) & 0x0F, TodayDate & 0x1F,
(TodayDate >> 9) & 0x7F);
i = atoi(Str);
JtoG(Today - i, &Arg1, &Arg2, &Arg3);
Arg3 += 80;
}
if (Arg1 > 31) {
Year = Arg1;
Month = Arg2;
Day = Arg3;
}
else {
Year = Arg3;
Month = Arg1;
Day = Arg2;
}
if (Month > 12 || Day > 31)
ErrorExit("\"%s\" Invalid date - %s\n", argv[i - 1], argv[i]);
if (Year > 100) Year -= 1980;
else Year -= 80;
}
Date->Date = (Year << 9) | (Month << 5) | Day;
Date->Swt = 1;
return (i);
}
/************************************************************************/
/* *** GtoJ.c *** */
/* */
/* This function converts a gregorian date, in the ( month, day, year ) */
/* format, into its respective julian, or day number, equivalent. */
/* ( 1 = 1st day AD ) */
/* */
/* The legal input values, in their proper order, are: */
/* */
/* month = 1 to 12 ( unsigned int ) */
/* day = 1 to 31 ( unsigned int ) */
/* year = 0 to 9999 ( unsigned int ) */
/* */
/* The return value of the function is the julian day number */
/* expressed as an unsigned long integer. */
/* */
/************************************************************************/
long
GtoJ (unsigned m, unsigned d, unsigned y) {
y += (m += 9) / 12 + 399;
m %= 12;
return ((long) y * 365 + y / 4 - y / 100 + y / 400 + (153 * m + 2) / 5 + d - 146037L);
}
/************************************************************************/
/* *** JtoG.c *** */
/* */
/* This function converts a julian day number ( 1 = 1st day AD ), into */
/* either a gregorian date character string, in any one of the four */
/* formats described below, or an array of three integers representing */
/* the month, day, and year, respectively, of the equivalent gregorian */
/* date. Storage for the output is provided by the calling routine. */
/* */
/* The input values, in their proper order, are: */
/* */
/* 1. the julian date to be converted, ( unsigned long ) */
/* */
/* 2. a pointer to the output array, ( char * ) */
/* */
/* 3. the format code ( described below ) */
/* specifying the desired output format. ( unsigned int ) */
/* */
/* The format codes are defined as follows: */
/* */
/* CODE - EXPLANATION - */
/* */
/* 0 - output array will hold three integers defined as: */
/* */
/* array[0] = month ( mm ) */
/* array[1] = day ( dd ) */
/* array[2] = Year ( yyyy ) */
/* */
/* If this format option is used, a type cast will have to */
/* be performed on the output pointer to convert it to the */
/* appropriate pointer type. ( see example below ) */
/* */
/* 1 - output string will hold a character string in the */
/* format "mmddyy" ( minimum - char string[7] ) */
/* */
/* 2 - output string will hold a character string in the */
/* format "mmddyyyy" ( minimum - char string[9] ) */
/* */
/* 3 - output string will hold a character string in the */
/* format "mm/dd/yy" ( minimum - char string[9] ) */
/* */
/* 4 - output string will hold a character string in the */
/* format "mm/dd/yyyy" ( minimum - char string[11] ) */
/* */
/* NOTE - input of any format code not listed above will be */
/* interpreted as code 0. */
/* */
/* The function returns a character pointer to the output array. */
/* _________________________________________________________________ */
/* | *** example of integer array output *** | */
/* | | */
/* | int Month, dte_array[3]; | */
/* | long julian = 548784; | */
/* | | */
/* | Month = ( (int *)JtoG( Julian, (char *)dte_array, 0 ) )[0]; | */
/* |________________________________________________________________| */
/* */
/* WARNING - the output array pointed to must be dimensioned */
/* accordingly or a memory overwrite will occur. */
/************************************************************************/
void
JtoG (long Julian, int *Month, int *Day, int *Year) {
*Year = (int) ((Julian += 146037L) * 400 / 146097L);
Julian -= (long) *Year * 365 + *Year / 4 - *Year / 100 + *Year / 400;
if (!Julian) Julian = 365 + !(*Year % 4), --*Year;
*Year += (*Month = (*Day = (int) Julian * 5 - 3) / 153 + 2) / 12 - 400;
*Month = *Month % 12 + 1;
*Day = *Day % 153 / 5 + 1;
}
/*
* ISDEVICE - Will invoke Ms-Dos IOCTL function to "get" the attributes of
* the specified DOS handle.
*
* Result := True If the specified handle is a device.
* := False If the specified handle is a file.
*
* Caution: A True return only indicates that the handle is assigned to a device
* driver. These include the CON, PRN, AUX and any user installed device
* drivers.
*
* A False return indicates that the handle is assigned to a file that may be on
* a Floppy, Hard Disk or Ram Disk.
*/
int
isdevice (int handle) {
union REGS R;
R.x.ax = 0x4400; /* MS-DOS IOCTL "Get" function */
R.x.bx = handle; /* ... Handle for IOCTL "Get" */
R.x.dx = 0;
intdos(&R, &R); /* ... MS-DOS Entry Interrupt */
if ((R.x.dx & 0x80) == 0) return (0);
else return (1);
}
int
GetDirRef (char **Ref, char **argv, int i) {
if (argv[i + 1][0] == '\0' || argv[i + 1][0] == '-')
ErrorExit("\"%s\" requires a directory argument.", argv[i]);
if ((*Ref = malloc(66)) == NULL)
ErrorMsg("Insufficient memory for \"%s\".", argv[i]);
else RootPath(CurDir, argv[++i], *Ref);
return (i);
}
int
GetFileRef (INFO_BLOCK **Ref, char **argv, int i) {
struct ffblk DirBlk;
if (argv[i + 1][0] == '\0' || argv[i + 1][0] == '-')
ErrorExit("\"%s\" requires a filename argument.", argv[i]);
if ((*Ref = malloc(sizeof(INFO_BLOCK))) == NULL)
ErrorMsg("Insufficient memory for \"%s\" reference.", argv[i]);
else {
RootPath(CurDir, argv[++i], (*Ref)->Name);
if (findfirst((*Ref)->Name, &DirBlk, (FA_SYSTEM | FA_RDONLY | FA_HIDDEN | FA_ARCH)))
ErrorExit("\"%s\" - %s", argv[i - 1], argv[i]);
(*Ref)->Attrib = DirBlk.ff_attrib;
(*Ref)->FTime.Time = DirBlk.ff_ftime;
(*Ref)->FDate.Date = DirBlk.ff_fdate;
(*Ref)->Size = DirBlk.ff_fsize;
}
return (i);
}
void
SetCopyMove (char *argv[], int *i, int *Swt) {
char *p;
if (argv[*i + 1] == NULL || argv[*i + 1][0] == '-')
strcpy(DestDir, CurDir);
else if ( !strcmp(argv[*i + 1], ".") ) strcpy(DestDir, CurDir);
else if ( !strcmp(argv[*i + 1], "..") ) {
CurDir[strlen(CurDir)-1] = '\0';
*(p = strrchr(CurDir, '\\')) = '\0';
strcpy(DestDir, CurDir); strcat(DestDir, "\\");
*p = '\\';
strcat(CurDir, "\\");
}
else RootPath(CurDir, argv[++*i], DestDir);
*Swt = 1;
PrtSwt &= 0xFE;
}